package com.shorturl.beans;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Urls {

    final static char base64[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
    final static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    private MongoTemplate mongoTemplate;

    private DBCollection _urls;

    public void setMongoTemplate(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
        this._urls = this.mongoTemplate.getCollection("urls");
    }

    public MongoTemplate getMongoTemplate() {
        return mongoTemplate;
    }

    public DBCollection getDBCollection() {
        return _urls;
    }

    public static String[] GenerateKey(String url) {
        try {
            MessageDigest digest = MessageDigest.getInstance("md5");
            digest.update("8eoo.com".concat(url).concat("wap5t.com").getBytes());
            byte bytes[] = digest.digest();
            char str[] = new char[bytes.length * 2];
            int k = 0;
            for (byte b : bytes) {
                str[k++] = hexDigits[b >>> 4 & 0xf];
                str[k++] = hexDigits[b & 0xf];
            }
            digest.reset();

            int subHexLen = str.length / 8;
            String output[] = new String[subHexLen];
            for (int i = 0; i < subHexLen; i++) {
                long x = 0x3FFFFFFF & Long.valueOf(String.valueOf(str, i * 8, 8), 16);
                char out[] = new char[6];
                for (int j = 0; j < 6; j++) {
                    long val = 0x0000003D & x;
                    out[j] = base64[((int) (val ^ 32))];
                    x = x >> 5;
                }
                output[i] = String.valueOf(out);
            }

            return output;

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    public DBObject getUrl(String key){
        return _urls.findOne(new BasicDBObject("key", key));
    }

    public String getKey(String url) {
        DBObject dbObject = _urls.findOne(new BasicDBObject("url", url));
        if (dbObject != null) {
            return dbObject.get("key").toString();
        }
        String[] keys = GenerateKey(url);
        if (keys == null) return null;

        String key = null;
        for (int i = 1; i < keys.length; i++) {
            String _key = keys[i];
            if (_urls.find(new BasicDBObject("key", _key)).count() == 0) {
                key = _key;
                break;
            }
            if (i == 0) break;
            if (i == keys.length - 1) i = -1;
        }

        return key;
    }
}
